﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using AForge.Controls;
using AForge.Video.DirectShow;
using AForge.Video.VFW;
using AForge.Vision.Motion;
using AForge.Imaging;

namespace Видеонаблюдение
{
    public partial class mainForm : Form
    {
        #region Общие переменные
        FilterInfoCollection videoDevices;
        VideoCaptureDevice videoSource;
        VideoCaptureDevice videoSource2;
        AVIWriter videoWriter;
        AVIWriter videoWriter2;
        MotionDetector detector = new MotionDetector(new TwoFramesDifferenceDetector());
        MotionDetector detector2 = new MotionDetector(new TwoFramesDifferenceDetector());
        private float motionAlarmLevel = 0.015f;
        #endregion

        public mainForm()
        {
            InitializeComponent();
        }

        #region Локальные методы
        private void SplitFrames(Bitmap frame1, Bitmap frame2)
        {
            Bitmap MasterFrame = new Bitmap(1280, 480);
            if (frame1 == null)
            { frame1 = new Bitmap(640, 480); }
            if (frame2 == null)
            { frame2 = new Bitmap(640, 480); }
            Graphics g = Graphics.FromImage(MasterFrame);
            g.DrawImage(frame1, 0, 0);
            g.DrawImage(frame2, 640, 0);
            g.Dispose();
            //pictureBox1.Image = MasterFrame;
            videoWriter.AddFrame(MasterFrame);
            //return MastAddFrameerFrame;
        }

        private void camerasUpdate()
        {
            camerasBox.Enabled = true;
            groupBox1.Enabled = true;
            groupBox2.Enabled = true;
            videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            if (videoDevices.Count == 0)
            {
                camerasBox.Items.Clear();
                camerasBox.Items.Add("Не найдено ни одной камеры");
                lbl.Text = "Не найдено ни одной камеры!";
                camerasBox.Enabled = false;
                sourcePlayer.Enabled = false;
                groupBox1.Enabled = false;
                groupBox2.Enabled = false;
            }
            else
            {
                camerasBox.Items.Clear();
                camerasBox2.Items.Clear();
                for (int i = 0; i < videoDevices.Count; i++)
                {
                    camerasBox.Items.Add(videoDevices[i].Name);
                    camerasBox2.Items.Add(videoDevices[i].Name);
                }

                lbl.Text = "Готово";
            }

            camerasBox.SelectedIndex = 0;
        }
        #endregion

        #region Обработчики

        #region Обработчики mainForm
        private void mainForm_Load(object sender, EventArgs e)
        {
            lbl.Text = "Готово";
            camerasUpdate();
            motionDetectionTip.SetToolTip(onDetectionBox, "Если распознование движения включено,\r\nто при движении в кадре будет произведиться запись.\r\nИначе запись будет проиводиться постоянно.");
            frameRateTip.SetToolTip(frameRateTxt, "Количество кадров в секунду в видео.");
            alarmLevelTip.SetToolTip(alarmLevelTxt, "Пороговый уровень движения, при превышении которого начнется запись.");
        }

        private void mainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            try
            {
                sourcePlayer.Stop();
                sourcePlayer2.Stop();
                videoSource.Stop();
                videoSource2.Stop();
                videoWriter.Close();
            }

            catch { }
        }

        #endregion

        #region Обработчики sourcePlayer`ов
        private void sourcePlayer_NewFrame(object sender, ref Bitmap img)
        {
            float motionAlarmLevel = 0.015f;// Convert.ToDouble(alarmLevelTxt.Text);
            if (onDetectionBox.Checked)
            {
                if (detector != null)
                {
                    float motionLevel = detector.ProcessFrame(img);
                    if (motionLevel > motionAlarmLevel)
                    {
                        if (dateBox.Checked)
                        {
                            Bitmap frame = img;
                            DateTime now = DateTime.Now;
                            Graphics g = Graphics.FromImage(frame);
                            SolidBrush brush = new SolidBrush(Color.Red);
                            g.DrawString(now.ToString(), this.Font, brush, new PointF(5, 5));
                            brush.Dispose();
                            g.Dispose();
                            //videoWriter.AddFrame(SplitFrames(img, sourcePlayer2.GetCurrentVideoFrame()));
                            //pictureBox1.Image = SplitFrames(img, sourcePlayer2.GetCurrentVideoFrame());
                            SplitFrames(img, sourcePlayer2.GetCurrentVideoFrame());
                        }
                        else 
                        {
                            //videoWriter.AddFrame(SplitFrames(img, sourcePlayer2.GetCurrentVideoFrame()));
                        }
                    }
                }
            }
            else
            {
                //videoWriter.AddFrame(SplitFrames(img, sourcePlayer2.GetCurrentVideoFrame()));
            }
        }

        private void sourcePlayer2_NewFrame(object sender, ref Bitmap img)
        {
            float motionAlarmLevel = 0.015f;// Convert.ToDouble(alarmLevelTxt.Text);
            if (onDetectionBox.Checked)
            {
                if (detector2 != null)
                {
                    float motionLevel = detector2.ProcessFrame(img);
                    if (motionLevel > motionAlarmLevel)
                    {
                        if (dateBox.Checked)
                        {
                            Bitmap frame = img;
                            DateTime now = DateTime.Now;
                            Graphics g = Graphics.FromImage(frame);
                            SolidBrush brush = new SolidBrush(Color.Red);
                            g.DrawString(now.ToString(), this.Font, brush, new PointF(5, 5));
                            brush.Dispose();
                            g.Dispose();
                            //videoWriter.AddFrame(SplitFrames(sourcePlayer.GetCurrentVideoFrame(), img));
                            //pictureBox1.Image = SplitFrames(img, sourcePlayer2.GetCurrentVideoFrame());
                            SplitFrames(sourcePlayer.GetCurrentVideoFrame(), img);
                        }
                        else
                        {
                           // videoWriter2.AddFrame(SplitFrames(sourcePlayer.GetCurrentVideoFrame(), img));
                        }
                    }
                }
            }
            else
            {
                //videoWriter.AddFrame(SplitFrames(sourcePlayer.GetCurrentVideoFrame(), img));
            }
        }

        #endregion

        #region Обработчики кнопок
        private void stopBtn_Click(object sender, EventArgs e)
        {
            videoWriter.Close();
            //videoWriter2.Close();
            //sourcePlayer.SignalToStop();
            //sourcePlayer2.SignalToStop();
            videoSource.SignalToStop();
            videoSource2.SignalToStop();
            stopBtn.Enabled = false;
            startBtn.Enabled = true;
            browseBtn.Enabled = true;
            fnameTxt.Enabled = true;
            frameRateTxt.Enabled = true;
            groupBox2.Enabled = true;
        }

        private void refreshBtn_Click(object sender, EventArgs e)
        {
            camerasUpdate();
        }

        private void browseBtn_Click(object sender, EventArgs e)
        {
            saveDialog.ShowDialog();
        }

        private void startBtn_Click(object sender, EventArgs e)
        {
            try{
            videoSource = new VideoCaptureDevice(videoDevices[camerasBox.SelectedIndex].MonikerString);
            videoSource.Start();
            sourcePlayer.VideoSource = videoSource;
            videoSource2 = new VideoCaptureDevice(videoDevices[camerasBox2.SelectedIndex].MonikerString);
            videoSource2.Start();
            sourcePlayer2.VideoSource = videoSource2;
            }
            catch{/*Ну и бог с ним*/}
            videoWriter = new AVIWriter("Xvid");
            videoWriter2 = new AVIWriter("Divx");
            videoWriter.FrameRate = Convert.ToInt32(frameRateTxt.Text);
            videoWriter2.FrameRate = Convert.ToInt32(frameRateTxt.Text);
            videoWriter.Open(fnameTxt.Text, 1280, 480);
            //videoWriter2.Open(fnameTxt2.Text, 640, 480);
            stopBtn.Enabled = true;
            startBtn.Enabled = false;
        }
        #endregion
        #endregion

        private void saveDialog_FileOk(object sender, CancelEventArgs e)
        {
            fnameTxt.Text = saveDialog.FileName;
        }

        private void browseBtn2_Click(object sender, EventArgs e)
        {
            saveDialog2.ShowDialog();
        }

        private void saveDialog2_FileOk(object sender, CancelEventArgs e)
        {
            fnameTxt2.Text = saveDialog2.FileName;
        }

    }
}
